<?php
#
# dmBridge: a data access framework for CONTENTdm(R)
#
# Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
# Education, on behalf of the University of Nevada, Las Vegas
#

/**
 * A custom date class that extends PHP's built-in DateTime class. All
 * dates passed internally must be instances of this class, and dmBridge will
 * always return dates as objects of this type (except in object DC metadata
 * fields, which will always be returned as strings).
 *
 * To get data out of an object of this type, use the format()
 * method, which accepts the same parameters as PHP's date() function.
 * The constructor accepts a date string pretty similar to strtotime().
 *
 * The DateTime class methods (for reference):
 * __construct, format, modify, getTimezone, setTimezone, getOffset, setTime,
 * setDate, setISODate
 *
 * @author Alex Dolski <alex.dolski@unlv.edu>
 * @license http://www.opensource.org/licenses/mit-license.php
 */
class DMDateTime extends DateTime {

	private $string_representation; // for the benefit of __sleep() & __wakeup()


	/**
	 * @param $datetime_str A date/time string recognizable by strtotime()
	 * @since 0.1
	 */
	public function __construct($datetime_str=null) {
		parent::__construct($datetime_str);
	}

	/**
	 * Returns a human-readable date/time. The format may change and should not
	 * be depended on.
	 * @return string
	 * @see dmDateTime::format()
	 * @since 0.1
	 */
	public function __toString() {
		return $this->format('Y-m-d @ h:i:s A');
	}

	/**
	 * This method works around the fact that built-in PHP objects cannot be
	 * serialized.
	 * @see __wakeup()
	 * @since 0.1
	 */
	public function __sleep() {
		$this->string_representation = $this->format('c');
		return array('string_representation');
	}

	/**
	 * This method works around the fact that built-in PHP objects cannot be
	 * serialized.
	 * @see __sleep()
	 * @since 0.1
	 */
	public function __wakeup() {
		$this->__construct($this->string_representation);
	}

	/**
	 * @return ISO8601-formatted date string
	 * @since 0.1
	 */
	public function asISO8601() {
		return $this->format('c');
	}

	/**
	 * @return String compatible with a MySQL DATETIME field
	 * @since 0.1
	 */
	public function asMySQLDateTime() {
		return $this->format('Y-m-d h:i:s');
	}

	/**
	 * RFC822 dates are used by RSS feeds, among other potential other uses.
	 * @return string
	 * @since 0.1
	 */
	public function asRFC822() {
		return $this->format('r');
	}

	/**
	 * RFC3339 dates are used by Atom feeds, among other potential other uses.
	 * @return string
	 * @since 0.1
	 */
	public function asRFC3339() {
		$date = $this->format('Y-m-d\TH:i:s');
		$p = array();
		if (preg_match('/^([\-+])(\d{2})(\d{2})$/', $this->format('O'), $p)) {
			$date .= $p[1] . $p[2] . ':' . $p[3];
		}
		else $date .= 'Z';
		return $date;
	}

	/**
	 * @return string
	 * @since 0.1
	 */
	public function asUnixTimestamp() {
		return $this->format('U');
	}

	/**
	 * @param mixed obj
	 * @return boolean
	 */
	public function equals($obj) {
		if (!$obj instanceof DMDateTime) {
			return false;
		}
		return ($this->asUnixTimestamp() == $obj->asUnixTimestamp());
	}

}
